<?php

declare (strict_types=1);

namespace magein\pay;

use magein\pay\extension\PayLogInterface;
use magein\pay\extension\PayOrderInterface;
use magein\pay\extension\PayQrcodeOrderInterface;
use magein\pay\extension\WxOauthInterface;
use magein\pay\platform\AliPay;
use magein\pay\platform\WxPay;

class PayFactory
{

    /**
     * 获取支付平台实例
     * @param array|string $param
     * @return AliPay|WxPay|null
     * @throws PayException
     */
    public static function platform($param)
    {
        if (is_array($param)) {
            $platform_id = $param['platform_id'] ?? '';
        } else {
            $platform_id = $param;
        }

        $platform = PayConfig::platforms($platform_id)['platform'] ?? [];
        if (empty($platform_id) || empty($platform)) {
            PayException::code(PayCode::PLATFORM_NULL);
        }

        try {
            $class = $platform ? new $platform() : null;
        } catch (\Exception $exception) {
            $class = null;
        }

        if (empty($class) || !$class instanceof PayPlatform) {
            PayException::code(PayCode::PLATFORM_CLASS_NULL);
        }

        return $class;
    }


    /**
     * @param $name
     * @return mixed|null
     * @throws PayException
     */
    public static function getExtensionClass($name)
    {
        $namespace = PayConfig::instance()->extension($name);

        $class = null;
        $message = '';
        try {
            if (class_exists($namespace)) {
                $class = new $namespace();
            }
        } catch (\Exception $exception) {
            $message = $exception->getMessage();
        }

        if ($message) {
            PayException::json($message);
        }

        return $class;
    }

    /**
     * 支付订单类
     * @return PayOrderInterface
     * @throws PayException
     */
    public static function order(): PayOrderInterface
    {
        $class = self::getExtensionClass('pay_order');

        if (!$class instanceof PayOrderInterface) {
            PayException::json('PayOrder need instanceof PayOrderInterface');
        }

        return $class;
    }


    /**
     * @return PayNotice
     * @throws PayException
     */
    public static function notice(): PayNotice
    {
        $class = self::getExtensionClass('pay_notice');

        if (empty($class)) {
            $class = new PayNotice();
        }

        if (!$class instanceof PayNotice) {
            PayException::json('PayNotice need instanceof PayNotice');
        }

        return $class;
    }

    /**
     * @return PayLogInterface
     * @throws PayException
     */
    public static function log(): PayLogInterface
    {
        $class = self::getExtensionClass('pay_log');

        if (!$class instanceof PayLogInterface) {
            PayException::json('PayLog need instanceof PayLogInterface');
        }

        return $class;
    }

    /**
     * @return PaySigner
     * @throws PayException
     */
    public static function singer(): PaySigner
    {
        $class = self::getExtensionClass('pay_singer');

        if (!$class instanceof PaySigner) {
            PayException::json('PaySigner need instanceof PaySignerInterface');
        }

        return $class;
    }

    /**
     * @throws PayException
     */
    public static function qrcode()
    {
        $class = self::getExtensionClass('pay_qrcode');

        if (!$class instanceof PayQrcodeOrderInterface) {
            PayException::json('PayQrcode need instanceof PayQrcodeOrderInterface');
        }

        return $class;
    }

    /**
     * @throws PayException
     */
    public static function wxOauth()
    {
        $class = self::getExtensionClass('wx_oauth');

        if (!$class instanceof WxOauthInterface) {
            PayException::json('WxOauth need instanceof WxOauthInterface');
        }

        return $class;
    }
}